package nachos.threads;

import nachos.machine.*;

public class Child extends WorldStateListener implements Runnable {

   private static Child rider = null;
   private static Child rower = null;

   public Child() {
      super();
   }

   /**
    * determine whether child is rower or rider
    */
   public void run() {
      while( shouldRun() ) {
         //System.out.println( certainties() );
         //critical section start
         if( island == OAHU 
               && Boat.side() == OAHU 
               && boatIsEmpty() ) {
            System.out.println( "found rower" );
            makeMyselfRower();
            getInBoat();
            Boat.childMutex.P();
            Boat.bg.ChildRowToMolokai();
            cross();
            KThread.currentThread().yield();
         } else if ( island == OAHU 
               && Boat.side() == OAHU 
               && childInBoat() ) {
            if( rower != this && rider == null) {
               System.out.println( "found rider" );
               Boat.bg.ChildRideToMolokai();
               makeMyselfRider();
               getInBoat();
               island = MOLOKAI;
               Boat.childMutex.V();
               KThread.currentThread().yield();
            }
         } else if ( island == MOLOKAI 
               && Boat.side() == MOLOKAI 
               && boatIsEmpty() ) {
            getInBoat();
            cross();
            Boat.bg.ChildRowToOahu();
            Boat.condlock.acquire();
            Boat.condstate = true;
            Boat.condition.wakeAll();
            Boat.condlock.release();
            //Machine.halt();
            KThread.currentThread().yield();
         } else {
            KThread.currentThread().yield();
         }
         //critical section end
         KThread.currentThread().yield();
      }
      //KThread.finish();
   }

   /**
    * places child in boat and updates empty boat boolean
    */
   private void getInBoat() {
      Boat.empty = false;
   }

   /**
    * @return true if boat has a rower
    */
   private boolean childInBoat() {
      return (rower != null);
   }

   /**
    * place child in rower seat
    */
   private void makeMyselfRower() {
      rower = this;
   }

   /**
    * place child in rider seat
    */
   private void makeMyselfRider() {
      rider = this;
   }

   /**
    * cross boat to other island and allow child(ren) to exit
    */
   public void cross() {
      super.cross();
      if (island == OAHU) {
         island = MOLOKAI;
      } else {
         island = OAHU;
      }
      rower = null;
      rider = null;
   }

}

